package com.asm;

import com.asm.RegisterType;

public class Register extends Operand {
    RegisterType registerType;
    Type type;

    public Register(RegisterType registerType, Type type) {
        this.registerType = registerType;
        this.type = type;
    }

    public Register forType(Type t) {
        return new Register(registerType, t);
    }

    public boolean isRegister() {
        return true;
    }

    public void collectStatistics(Statistics stats) {
        stats.registerUsed(this);
    }

    public boolean equals(Object other) {
        return (other instanceof Register) && equals((Register) other);
    }

    /** size difference does NOT matter. */
    public boolean equals(Register reg) {
        return registerType.equals(reg.registerType);
    }

    public int hashCode() {
        return registerType.hashCode();
    }

    RegisterType getRegisterType() {
        return registerType;
    }

    String baseName() {
        return registerType.toString().toLowerCase();
    }

    public String toSource(SymbolTable table) {
        String ret = "r";
        switch (registerType) {
            case R0:
                ret += "0";
                break;
            case R1:
                ret += "1";
                break;
            case R2:
                ret += "2";
                break;
            case R3:
                ret += "3";
                break;
            case R4:
                ret += "4";
                break;
            case R5:
                ret += "5";
                break;
            case R6:
                ret += "6";
                break;
            case R7:
                ret += "7";
                break;
            case R8:
                ret += "8";
                break;
            case R9:
                ret += "9";
                break;
            case R10:
                ret += "10";
                break;
            case fp:
                ret = "fp";
                break;
            case ip:
                ret = "ip";
                break;
            case sp:
                ret = "sp";
                break;
            case lr:
                ret = "lr";
                break;
            default:
                ret = "pc";
                break;
        }
        return ret;
    }

    // private String typedName() {
    // switch (type) {
    // case INT8: return lowerByteRegister();
    // case INT16: return baseName();
    // case INT32: return "e" + baseName();
    // case INT64: return "r" + baseName();
    // default:
    // throw new Error("unknown register Type: " + type);
    // }
    // }

    // private String lowerByteRegister() {
    // switch (_class) {
    // case AX:
    // case BX:
    // case CX:
    // case DX:
    // return baseName().substring(0, 1) + "l";
    // default:
    // throw new Error("does not have lower-byte register: " + _class);
    // }
    // }

    public String dump() {
        return "(Register " + registerType.toString() + " " + type.toString() + ")";
    }
}
